<?php
/**
 * Created by PhpStorm.
 * User: tangsian
 * Date: 2020/12/18
 * Time: 12:04
 */

namespace App\Http\Model;


use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class SoundByte extends Base
{
    protected $connection = "mysql_kkaudio";
    protected $cacheRedisKeySoundByte = 'CACHE:SOUND_BYTE:TYPE:';
    protected $cacheRedisKeySoundByteSmallHouse = 'CACHE:SOUND_BYTE:SMALL_HOUSE:';
    protected $cacheRedisKeySoundByteFamily = 'CACHE:SOUND_BYTE:FAMILY:LIST';
    protected $cacheRedisKeySoundByteSendUserRank = 'CACHE:SOUND_BYTE:SEND_USER_RANK:LIST';
    protected $cacheRedisKeySoundByteFamilyUser = 'CACHE:SOUND_BYTE:FAMILY:FAMILY_USER';
    protected $cacheRedisKeySuspendTime = 'CACHE:SOUND_BYTE:SUSPEND_TIME';
    protected $cacheRedisKeyPersonalAdvancedList = 'CACHE:SOUND_BYTE:PERSONAL_ADVANCE_LIST';
    protected $cacheRedisKeySmallHouseAdvancedList = 'CACHE:SOUND_BYTE:SMALL_HOUSE_ADVANCE_LIST';
    protected $cacheRedisKeyAdvancedList = 'CACHE:SOUND_BYTE:ADVANCE_LIST';
    protected $cacheRedisKeyAdvancedListFamily = 'CACHE:SOUND_BYTE:ADVANCE_LIST:FAMILY';
    protected $cacheRedisKeyTimeStep = 'CACHE:SOUND_BYTE:SOUND_BYTE:TIME_STEP';
    protected $cacheUserFamilyInfo = 'CACHE:SOUND_BYTE:FAMILY_USER:USER';
    protected $timesAdvanceNum = [
        '1' => 12,
        '2' => 8,
        '3' => 4
    ];
    protected $timesArray = [
        0 => [
            'start_time' => 1610640000,
            'end_time' => 1610985600
        ],
        1 => [
            'start_time' => 1611158400,
            'end_time' => 1611331200
        ],
        2 => [
            'start_time' => 1611504000,
            'end_time' => 1611676800
        ],
        3 => [
            'start_time' => 1611849600,
            'end_time' => 1612022400
        ],
    ];

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }

    /**
     * 获取当前阶段的时间数据
     * @param $timeStep
     * @return mixed
     */
    public function getTimeStepTimeArray($timeStep = 0)
    {
        return $this->timesArray[$timeStep];
    }

    public function getTimeStep()
    {
        return intval(Redis::get($this->cacheRedisKeyTimeStep));
    }

    /**
     * 添加浪值计数
     * @param $type
     * @param $userId
     * @param $num
     */
    public function setPersonalSoundByteByType($type, $userId, $num)
    {
        $step = $this->getTimeStep();
        if (Redis::Exists($this->cacheRedisKeySuspendTime)) {
            return false;
        }

        if (Redis::Exists($this->cacheRedisKeyPersonalAdvancedList . '_' . $type) && !Redis::Sismember($this->cacheRedisKeyPersonalAdvancedList . '_' . $type, $userId)) {
            return false;
        }

        Redis::Zincrby($this->cacheRedisKeySoundByte . 'TYPE_' . $type . '_step_' . $step, $num, $userId);
        if (Redis::Ttl($this->cacheRedisKeySoundByte . 'TYPE_' . $type . '_step_' . $step) == -1) Redis::EXPIRE($this->cacheRedisKeySoundByte . 'TYPE_' . $type . '_step_' . $step, 2592000*2);

        return true;
    }

    /**
     * 设置工会音浪数据
     * @param $familyUid
     * @param $roomId
     * @param $num
     */
    public function setFamilySoundByte($familyUid, $roomId, $num)
    {
        $step = $this->getTimeStep();
        if (Redis::Exists($this->cacheRedisKeySuspendTime)) {
            return false;
        }

        if (Redis::Exists($this->cacheRedisKeyAdvancedList) && !Redis::Sismember($this->cacheRedisKeyAdvancedList, $familyUid)) {
            return false;
        }

        Redis::Zincrby($this->cacheRedisKeySoundByteFamily . '_step_' . $step, $num, $familyUid);
        if (Redis::Ttl($this->cacheRedisKeySoundByteFamily . '_step_' . $step) == -1) Redis::EXPIRE($this->cacheRedisKeySoundByteFamily . '_step_' . $step, 2592000*2);

        Redis::Zincrby($this->cacheRedisKeySoundByteFamilyUser . '_' . $familyUid, $num, $roomId);
        if (Redis::Ttl($this->cacheRedisKeySoundByteFamilyUser . '_' . $familyUid) == -1) Redis::EXPIRE($this->cacheRedisKeySoundByteFamilyUser . '_' . $familyUid, 2592000*2);

        return true;
    }


    public function getFamilyByUserId($userId){
        if (Redis::Exists($this->cacheUserFamilyInfo . '_' . $userId)) {
            return Redis::get($this->cacheUserFamilyInfo . '_' . $userId);
        }
        $familyInfo=$this->objToArray(DB::connection($this->connection)->table('family_member')->join('family','family.family_id','=','family_member.family_id')->where('family_member.user_id','=',$userId)->first(['family_uid']));
        if(empty($familyInfo)){
            return false;
        }

        Redis::setex($this->cacheUserFamilyInfo . '_' . $userId, 200,$familyInfo['family_uid']);

        return $familyInfo['family_uid'];
    }

    /**
     * 根据类型获取个人音浪排行数据
     * @param $type
     * @param $page
     * @param $limit
     * @return mixed
     */
    public function soundBytePersonalListByType($type, $page, $limit)
    {
        $step = $this->getTimeStep();
        $data = [
            'list' => [],
            'total_count' => 0
        ];
        $start = 0;
        if ($page > 0) {
            $start = $page * $limit;
        }
        $end = ($page + 1) * $limit;

        if ($end >50) {
            $end = 50;
        }
        $data['list'] = Redis::Zrevrange($this->cacheRedisKeySoundByte . 'TYPE_' . $type . '_step_' . $step, $start, $end - 1, 'WITHSCORES');
        $data['total_count'] = Redis::Zcard($this->cacheRedisKeySoundByte . 'TYPE_' . $type . '_step_' . $step);
        return $data;
    }

    public function soundByteFamilyList($page, $limit)
    {
        $step = $this->getTimeStep();
        $data = [
            'list' => [],
            'total_count' => 0
        ];
        $start = 0;
        if ($page > 0) {
            $start = $page * $limit;
        }
        $end = ($page + 1) * $limit;

        if ($end >50) {
            $end = 50;
        }
        $data['list'] = Redis::Zrevrange($this->cacheRedisKeySoundByteFamily . '_step_' . $step, $start, $end - 1, 'WITHSCORES');
        $data['total_count'] = Redis::Zcard($this->cacheRedisKeySoundByteFamily . '_step_' . $step);
        return $data;
    }

    public function getFamilyRoomRank($familyUid, $page, $limit)
    {
        $step = $this->getTimeStep();
        $data = [
            'list' => [],
            'total_count' => 0
        ];
        $start = 0;
        if ($page > 0) {
            $start = $page * $limit;
        }
        $end = ($page + 1) * $limit;

        $data['list'] = Redis::Zrevrange($this->cacheRedisKeySoundByteFamilyUser . '_' . $familyUid, $start, $end - 1, 'WITHSCORES');
        $data['total_count'] = Redis::Zcard($this->cacheRedisKeySoundByteFamilyUser . '_' . $familyUid);
        return $data;
    }

    public function  soundByteFamilyScore($familyUid){
        $step = $this->getTimeStep();
        return doubleval(Redis::Zscore($this->cacheRedisKeySoundByteFamily . '_step_' . $step,$familyUid));
    }

    public function  soundByteFamilyRank($familyUid){
        $step = $this->getTimeStep();
        return Redis::Zrevrank($this->cacheRedisKeySoundByteFamily . '_step_' . $step,$familyUid);
    }

    public function soundBytePersonalScore($userId, $type)
    {
        $step = $this->getTimeStep();
        return doubleval(Redis::Zscore($this->cacheRedisKeySoundByte . 'TYPE_' . $type . '_step_' . $step, $userId));
    }

    public function soundBytePersonalRank($userId, $type)
    {
        $step = $this->getTimeStep();
        return Redis::Zrevrank($this->cacheRedisKeySoundByte . 'TYPE_' . $type . '_step_' . $step, $userId);
    }

    ####神豪###
    /*
     * 设置送出礼物排行
     */
    public function setSendUserRank($user_id, $to_user_id_array, int $gift_num)
    {
        $step = $this->getTimeStep();
        $count = count($to_user_id_array);
        if (empty($user_id) || $count < 1) {
            return fasle;
        }

        Redis::Zincrby($this->cacheRedisKeySoundByteSendUserRank, $count * $gift_num, $user_id);

        if (Redis::Ttl($this->cacheRedisKeySoundByteSendUserRank) == -1) Redis::EXPIRE($this->cacheRedisKeySoundByteSendUserRank . '_step_' . $step, 2592000*2);
    }

    /*
     * 获取当前送出声浪数据
     */
    public function soundByteSendUserScore($userId)
    {
        $step = $this->getTimeStep();
        return intval(Redis::Zscore($this->cacheRedisKeySoundByteSendUserRank, $userId));
    }

    public function soundByteSendUserRank($userId)
    {
        $step = $this->getTimeStep();
        return Redis::Zrevrank($this->cacheRedisKeySoundByteSendUserRank, $userId);
    }

    public function soundByteSendUserList($page, $limit)
    {
        $data = [
            'list' => [],
            'total_count' => 0
        ];
        $start = 0;
        if ($page > 0) {
            $start = $page * $limit;
        }
        $end = ($page + 1) * $limit;

        if ($end >50) {
            $end = 50;
        }
        $data['list'] = Redis::Zrevrange($this->cacheRedisKeySoundByteSendUserRank, $start, $end - 1, 'WITHSCORES');
        $data['total_count'] = Redis::Zcard($this->cacheRedisKeySoundByteSendUserRank);
        return $data;
    }

    #####窝神#####

    public function setSmallHouseSoundByteByType($userId, $num)
    {
        $step = $this->getTimeStep();
        if (Redis::Exists($this->cacheRedisKeySuspendTime)) {
            return false;
        }

        if (Redis::Exists($this->cacheRedisKeySmallHouseAdvancedList) && !Redis::Sismember($this->cacheRedisKeySmallHouseAdvancedList, $userId)) {
            return false;
        }

        Redis::Zincrby($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, $num, $userId);
        if (Redis::Ttl($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step) == -1) Redis::EXPIRE($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, 2592000*2);

        return true;
    }

    /*
 * 获取当前送出声浪数据
 */
    public function soundByteSmallHouseScore($userId)
    {
        $step = $this->getTimeStep();
        return doubleval(Redis::Zscore($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, $userId));
    }

    public function soundByteSmallHouseRank($userId)
    {
        $step = $this->getTimeStep();
        return Redis::Zrevrank($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, $userId);
    }

    public function soundByteSmallHouseList($page, $limit)
    {
        $step = $this->getTimeStep();
        $data = [
            'list' => [],
            'total_count' => 0
        ];
        $start = 0;
        if ($page > 0) {
            $start = $page * $limit;
        }
        $end = ($page + 1) * $limit;

        if ($end >50) {
            $end = 50;
        }
        $data['list'] = Redis::Zrevrange($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, $start, $end - 1, 'WITHSCORES');
        $data['total_count'] = Redis::Zcard($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step);
        return $data;
    }


    public function setSuspendTime($time = 84600)
    {
        Redis::setex($this->cacheRedisKeySuspendTime, $time, 1);
        return true;
    }

    public function setAdvancedList($typeArr)
    {
        $step = $this->getTimeStep();
        if ($step == 0) {
            $num = $this->timesAdvanceNum[$step + 1];
            $result = $this->addUserToAdvancedList($num, $typeArr);
            $extendResult = $this->extendList($step, $typeArr);
        } else {
            $num = $this->timesAdvanceNum[$step + 1];
            $prevNum = $this->timesAdvanceNum[$step];
            $result = $this->delUserToAdvancedList($num, $prevNum, $typeArr);
            $extendResult = $this->extendList($step, $typeArr);
        }

        if ($result && $extendResult) {
            Redis::setex($this->cacheRedisKeyTimeStep, 2592000*2, $step + 1);
        }
    }

    public function addUserToAdvancedList($num, $typeArr)
    {
        $step = $this->getTimeStep();
        foreach ($typeArr as $val) {
            $list = Redis::Zrevrange($this->cacheRedisKeySoundByte . 'TYPE' . '_' . $val . '_step_' . $step, 0, $num - 1);
            foreach ($list as $value) {
                Redis::Sadd($this->cacheRedisKeyPersonalAdvancedList . '_' . $val, $value);
            }
        }

        $smallHouseList = Redis::Zrevrange($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, 0, $num - 1);
        foreach ($smallHouseList as $smallHouseVal) {
            Redis::Sadd($this->cacheRedisKeySmallHouseAdvancedList, $smallHouseVal);
        }

        $familyList = Redis::Zrevrange($this->cacheRedisKeySoundByteFamily . '_step_' . $step, 0, $num - 1);
        foreach ($familyList as $familyVal) {
            Redis::Sadd($this->cacheRedisKeyAdvancedList, $familyVal);
        }
        return true;
    }

    public function delUserToAdvancedList($num, $prevNum, $typeArr)
    {
        $step = $this->getTimeStep();
        foreach ($typeArr as $val) {
            $list = Redis::Zrevrange($this->cacheRedisKeySoundByte . 'TYPE' . '_' . $val . '_step_' . $step, $num, $prevNum - 1);
            foreach ($list as $value) {
                Redis::Srem($this->cacheRedisKeyPersonalAdvancedList . '_' . $val, $value);
            }
        }

        $smallHouseList = Redis::Zrevrange($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, $num, $prevNum - 1);
        foreach ($smallHouseList as $smallHouseVal) {
            Redis::Srem($this->cacheRedisKeySmallHouseAdvancedList, $smallHouseVal);
        }

        $familyList = Redis::Zrevrange($this->cacheRedisKeySoundByteFamily . '_step_' . $step, $num, $prevNum - 1);
        foreach ($familyList as $familyVal) {
            Redis::Srem($this->cacheRedisKeyAdvancedList, $familyVal);
        }

        return true;
    }

    public function extendList($step, $typeArr)
    {
        $nextStep = $step + 1;
        foreach ($typeArr as $val) {
            $list = Redis::Zrevrange($this->cacheRedisKeySoundByte . 'TYPE' . '_' . $val . '_step_' . $step, 0, -1, 'WITHSCORES');
            foreach ($list as $key => $value) {
                Redis::Zadd($this->cacheRedisKeySoundByte . 'TYPE_' . $val . '_step_' . $nextStep,$value * 0.2, $key);
            }
        }

        $smallHouseList = Redis::Zrevrange($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $step, 0, -1, 'WITHSCORES');
        foreach ($smallHouseList as $smallKey => $smallHouseVal) {
            Redis::Zadd($this->cacheRedisKeySoundByteSmallHouse . '_step_' . $nextStep,$smallHouseVal * 0.2, $smallKey);
        }

        $familyList = Redis::Zrevrange($this->cacheRedisKeySoundByteFamily . '_step_' . $step, 0, -1, 'WITHSCORES');
        foreach ($familyList as $familyKey => $familyVal) {
            Redis::Zadd($this->cacheRedisKeySoundByteFamily . '_step_' . $nextStep,$familyVal * 0.2, $familyKey);
        }
        return true;
    }

    //获取工会进阶数据
    public function getFamilyAdvancedList()
    {
        return Redis::Smembers($this->cacheRedisKeyAdvancedList);
    }

    //获取窝神进阶数据
    public function geSmallHouseAdvancedList()
    {
        return Redis::Smembers($this->cacheRedisKeySmallHouseAdvancedList);
    }

    //获取个人进阶数据
    public function getPersonalTypeAdvancedList($type)
    {
        return Redis::Smembers($this->cacheRedisKeyPersonalAdvancedList . '_' . $type);
    }
}
